let path = require("path");
/* {
  copyDir: [AsyncFunction: copyDir],
  execute: [Function: execute],
  mkDir: [AsyncFunction: mkDir],
  isExist: [AsyncFunction: isExist],
  emptyDir: [Function: emptyDir],
  md5: [Function: md5],
  readFilesToString: [Function: readFilesToString],
  readDirs: [Function: readDirs],
  sleep: [Function: sleep]
} */
module.exports = {
  // 复制目录
  async copyDir(src, dst) {
    let cmd = `xcopy /y /r /c /h /e /i ${src} ${dst}`;
    let rs = await this.execute(cmd);
    if (rs === "error") {
      return "error:fail to copy";
    }
    return "success";
  },
  // 执行命令函数
  execute(cmd, execPath) {
    let cp = require("child_process");
    return new Promise((resolve, reject) => {
      let opts = {};
      if (execPath) {
        opts = {
          cwd: execPath,
        };
      }
      cp.exec(cmd, opts, (err, stdout) => {
        if (err) {
          resolve("error:execute failed");
        } else {
          resolve(stdout);
        }
      });
    });
  },
  // 创建文件夹
  async mkDir(folderPath) {
    let cmd = `md ${folderPath}`;
    let rs = await this.execute(cmd);
    if (rs === "error") {
      return "error:fail to copy";
    }
    return "success";
  },
  //   检测文件或文件夹是否存在
  async isExist(p1) {
    const fs = require("fs");
    try {
      fs.statSync(p1);
      return "success";
    } catch (e) {
      return "error:path does not exist";
    }
  },
  // 清空文件夹内所有文件
  emptyDir(fileUrl) {
    let _this = this;
    let fs = require("fs");
    //读取该文件夹
    let files = fs.readdirSync(fileUrl);
    files.forEach(function (file) {
      let tmpPath = path.resolve(fileUrl, ".", file);
      var stats = fs.statSync(tmpPath);
      if (stats.isDirectory()) {
        _this.emptyDir(tmpPath);
      } else {
        fs.unlinkSync(tmpPath);
      }
    });
  },
  md5(str) {
    let md5 = require("md5-node");
    return md5(str);
  },
  // 读取多个文件，生成一个字符串
  readFilesToString() {
    const fs = require("fs");
    let args = [...arguments];
    let result = [];
    args.forEach((p1) => {
      result.push(fs.readFileSync(p1).toString());
    });
    return result.join("\n");
  },
  // 读取文件夹下所有的HTML
  readDirs(path, result = []) {
    let fs = require("fs");
    let dirs = fs.readdirSync(path);
    dirs.forEach((item, index) => {
      let fullPath = path + "\\" + item;
      if (
        fullPath.includes("node_modules") ||
        fullPath.includes(".git") ||
        fullPath.includes(".vscode")
      ) {
        return;
      }
      let isDir = fs.statSync(fullPath).isDirectory();
      if (isDir) {
        // 是目录
        this.readDirs(fullPath, result);
      } else {
        result.push(fullPath);
      }
    });
    return result;
  },
  // 睡眠函数
  sleep(ms) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("success");
      }, ms);
    });
  },
  // 获取桌面路径
  getDeskPath() {
    return require("os").homedir() + "\\Desktop";
  },
  // 获取文件路径所属文件夹
  getFileOwnFolder(p) {
    p = p.replace(/\\/g, "/").replace(/^\//g, "");
    let arr = p.split(/\//);
    arr.pop();
    return arr.join("\\");
  },
  // 用于读取用户在终端输入的字符串，返回一个Promsie
  readLine(tips) {
    // prettier安装1.19.1
    const readline = require("readline");
    tips = tips || "> ";
    return new Promise((resolve) => {
      const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
      });

      rl.question(tips, (answer) => {
        rl.close();
        resolve(answer.trim());
      });
    });
  },
  // 读取一个目录下所有的.git仓库目录
  getAllGitBase(folder) {
    const fs = require("fs");
    let arr = [];
    let traverse = function (folder, cont, lastIndex = "") {
      // lastIndex可用于递归最大次数
      // lastIndex && console.log(lastIndex)
      if (lastIndex.length === 20) {
        return;
      }
      let list = fs.readdirSync(folder);
      // 递归退出条件
      if (list.includes(".git")) {
        cont.push(folder);
        return;
      }
      list = list.map((item) => path.resolve(folder, item));
      // 递归查找仓库
      list.forEach((item, index) => {
        try {
          let isDir = fs.statSync(item).isDirectory();
          let currentIndex = lastIndex ? lastIndex.concat(index) : [index];
          isDir && traverse(item, cont, currentIndex);
        } catch (e) {}
      });
    };
    traverse(folder, arr);
    return arr;
  },
  // 在nodejs终端输出带颜色字体
  print(color, msg) {
    let map = {
      bright: "\x1B[1m", // 亮色
      grey: "\x1B[2m", // 灰色
      italic: "\x1B[3m", // 斜体
      underline: "\x1B[4m", // 下划线
      reverse: "\x1B[7m", // 反向
      hidden: "\x1B[8m", // 隐藏
      black: "\x1B[30m", // 黑色
      red: "\x1B[31m", // 红色
      green: "\x1B[32m", // 绿色
      yellow: "\x1B[33m", // 黄色
      blue: "\x1B[34m", // 蓝色
      magenta: "\x1B[35m", // 品红
      cyan: "\x1B[36m", // 青色
      white: "\x1B[37m", // 白色
      blackBG: "\x1B[40m", // 背景色为黑色
      redBG: "\x1B[41m", // 背景色为红色
      greenBG: "\x1B[42m", // 背景色为绿色
      yellowBG: "\x1B[43m", // 背景色为黄色
      blueBG: "\x1B[44m", // 背景色为蓝色
      magentaBG: "\x1B[45m", // 背景色为品红
      cyanBG: "\x1B[46m", // 背景色为青色
      whiteBG: "\x1B[47m", // 背景色为白色
    };
    console.log(map[color] || map["bright"], msg, "\x1b[0m");
  },
  // 获取分支名称
  async getBranchName(execPath) {
    let branchName = await this.execute(
      "git rev-parse --abbrev-ref HEAD",
      execPath
    );
    if (!branchName || !branchName.trim()) return "";
    return branchName.trim();
  },
  // 获取当前打包人员
  async getCurrentPacker(execPath) {
    let userName = await this.execute("git config user.name", execPath);
    if (!userName || !userName.trim()) return "";
    return userName.trim();
  },
  // 获取当前打包人员邮箱
  async getCurrentPackerEmail(execPath) {
    let userEmail = await this.execute("git config user.email", execPath);
    if (!userEmail || !userEmail.trim()) return "";
    return userEmail.trim();
  },
  // 获取当前打包人员git版本
  async getGitVersion(execPath) {
    let gitVersion = await this.execute("git --version", execPath);
    if (!gitVersion || !gitVersion.trim()) return "";
    return gitVersion.trim();
  },
  // 获取当前打包人员node版本
  async getNodeVersion(execPath) {
    let nodeVersion = await this.execute("node -v", execPath);
    if (!nodeVersion || !nodeVersion.trim()) return "";
    return nodeVersion.trim();
  },
  // 获取当前打包人员prettier版本
  async getPrettierVersion(execPath) {
    let prettierVersion = await this.execute("prettier -v", execPath);
    if (!prettierVersion || !prettierVersion.trim()) return "";
    return prettierVersion.trim();
  },
  // 获取当前打包人员eslint版本
  async getEslintVersion(execPath) {
    let eslintVersion = await this.execute("eslint -v", execPath);
    if (!eslintVersion || !eslintVersion.trim()) return "";
    return eslintVersion.trim();
  },
  // 获取npm 版本
  async getNpmVersion(execPath) {
    let npmVersion = await this.execute("npm -v", execPath);
    if (!npmVersion || !npmVersion.trim()) return "";
    return npmVersion.trim();
  },
  // 获取当前改动相对于HEAD改动的文件数组
  async getChangedFiles(execPath) {
    let changedFiles = await this.execute(
      "git diff --name-only HEAD",
      execPath
    );
    if (!changedFiles || !changedFiles.trim()) return [];
    return changedFiles.trim().split("\n");
  },
  // 获取HEAD提交版本号和提交文案
  async getHeadCommitInfo(execPath) {
    let commitInfo = await this.execute(
      `git log -1 --pretty=format:"%h——%an——%s"`,
      execPath
    );
    if (!commitInfo || !commitInfo.trim()) return "";
    return commitInfo.trim();
  },
  // 获取当前的仓库地址
  async getRepoUrl(execPath) {
    let repoUrl = await this.execute("git config --get remote.origin.url", execPath);
    if (!repoUrl ||!repoUrl.trim()) return "";
    return repoUrl.trim();
  },
  // 时间格式化函数
  dateFormat(format, timestamp) {
    if (!(typeof format === "string")) {
      return null;
    }
    if (arguments.length < 2) {
      return null;
    }
    if (!/^\d+$/.test(timestamp) && !/^\d+\.\d+$/.test(timestamp)) {
      return null;
    }
    const milliSecs = timestamp * 1000;
    const dateObj = new Date(milliSecs);
    const year = dateObj.getFullYear();
    const month = dateObj.getMonth() + 1;
    const date = dateObj.getDate();
    const hour = dateObj.getHours();
    const min = dateObj.getMinutes();
    const sec = dateObj.getSeconds();
    const oDate = { year, month, date, hour, min, sec };
    const padZero = function (num) {
      return num < 10 ? "0" + num : "" + num;
    };
    const allKeys = "month,date,hour,min,sec";
    allKeys.split(",").forEach((key) => {
      oDate["fix" + key[0].toUpperCase() + key.slice(1)] = padZero(oDate[key]);
    });
    const regArr = [
      {
        key: /Y/g,
        value: oDate.year,
      },
      {
        key: /M/g,
        value: oDate.month,
      },
      {
        key: /D/g,
        value: oDate.date,
      },
      {
        key: /h/g,
        value: oDate.hour,
      },
      {
        key: /I/g,
        value: oDate.min,
      },
      {
        key: /S/g,
        value: oDate.sec,
      },
      {
        key: /m/g, // 小于10，补零
        value: oDate.fixMonth,
      },
      {
        key: /d/g, // 小于10，补零
        value: oDate.fixDate,
      },
      {
        key: /H/g, // 小于10，补零
        value: oDate.fixHour,
      },
      {
        key: /i/g, // 小于10，补零
        value: oDate.fixMin,
      },
      {
        key: /s/g, // 小于10，补零
        value: oDate.fixSec,
      },
    ];
    regArr.forEach((item) => {
      const { key, value } = item;
      format = format.replace(key, value);
    });
    return format;
  },
  
};
